package com.example.demo;

import java.util.Map;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;

@SpringBootApplication
public class GatewayApplication {

	public static void main(String[] args) {
		SpringApplication.run(GatewayApplication.class, args);
	}
	
	public @Bean GrayLevelFilter grayLevelFilter() { 
		return new GrayLevelFilter();
	}
	public @Bean  PathNoApiRoutePredicateFactory pathNoApiRoutePredicateFactory () {
		return new PathNoApiRoutePredicateFactory();
	}
	
	public @Bean  RewritePathBuildGatewayFilterFactory buildGatewayFilterFactory() {
		return new RewritePathBuildGatewayFilterFactory();
	}
	
	public @Bean GrayLevelRule grayLevelRule(){
		 return new GrayLevelRule();
	}
	
	@LoadBalanced
	public @Bean RestTemplate  restTemplate(NacosDiscoveryProperties discoveryProperties) {
		RestTemplate  restTemplate= new RestTemplate(); 
		Map<String, String> metadata = discoveryProperties.getMetadata(); 
		restTemplate.getInterceptors().add((HttpRequest request, byte[] body, ClientHttpRequestExecution execution)->{
			HttpHeaders headers = request.getHeaders();
			if(StringUtils.hasText(metadata.get(Const.GRAY_LEVEL_MARK))) {
				headers.add(Const.GRAY_LEVEL_MARK, metadata.get(Const.GRAY_LEVEL_MARK));
			}
		    return execution.execute(request, body);
		});
		return restTemplate;
	}
	 
	
	@Bean
//	@ConditionalOnBean(LoadBalancerClient.class)
	public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client,
			LoadBalancerProperties properties) { 
		return new LoadBalancerClientFilter(client, properties) { 
			@Override
			protected ServiceInstance choose(ServerWebExchange exchange) { 
 				try {
 					ServerWebExchangeContextHolder.setServerWebExchange(exchange);
 					return super.choose(exchange);
				} finally {
					ServerWebExchangeContextHolder.rest();
				}
			}
		};
	}
}
